import * as bcrypt from 'bcryptjs';
import { ConfigService } from '@nestjs/config';
import * as svgCaptcha from 'svg-captcha';
import * as jwt from 'jsonwebtoken';

import { User } from '@/modules/app/entities';
import { generateUUID } from '@/utils';

class CaptchaResult {
  id: string;
  imageBase64: string;
  text: string;
}

// 存储验证码的Map，key是验证码ID，value是验证码文本
const captchaMap = new Map<string, string>();

// export class Utils {
//   constructor(private readonly configService: ConfigService) {}

// }

export class CaptchaTool {
  constructor() {}
  /**
   * 生成验证码
   */
  generateCaptcha(): CaptchaResult {
    const captcha = svgCaptcha.create({
      size: 4, // 字符个数
      fontSize: 50, // 字体大小
      width: 120, // 图片宽度
      height: 40, // 图片高度
      noise: 0, // 干扰线数量
      color: true, // 是否开启颜色，默认为黑色
      background: '#cc9966',
      ignoreChars: '0oO1iIlL', // 验证码字符中排除 0o1i
    });

    const id = generateUUID();
    // 将验证码存入Map，并设置5分钟后自动删除
    captchaMap.set(id, captcha.text.toLowerCase());
    setTimeout(
      () => {
        captchaMap.delete(id);
      },
      5 * 60 * 1000,
    );

    return {
      id,
      imageBase64: captcha.data,
      text: captcha.text,
    };
  }

  /**
   * 保存验证码
   * @param session Session对象
   * @param email 邮箱
   * @param code 验证码
   */
  setCaptcha(session: Record<string, any>, email: string, code: string): void {
    session[`verification:${email}`] = code;
  }

  /**
   * 验证验证码
   * @param session Session对象
   * @param email 邮箱
   * @param code 验证码
   * @returns 是否有效
   */
  verifyCaptcha(
    session: Record<string, any>,
    email: string,
    code: string,
  ): boolean {
    const savedCode = session[`verification:${email}`];
    const isValid = savedCode === code;

    session[`verification:${email}`] = undefined; // 验证后删除验证码

    return isValid;
  }
}

/**
 *  private readonly jwt: JwtTool; 这个不需要injectable
 *  constructor 中需要
 */
export class JwtTool {
  private readonly secretKey = process.env.JWT_SECRET || 'your-secret-key';
  private readonly expiresIn = process.env.JWT_EXPIRES_IN || '24h';

  /**
   * 生成JWT令牌
   * @param user 用户信息
   * @returns JWT令牌
   */
  generateToken(user: User): string {
    // const secret = this.configService.get<string>('JWT_SECRET');
    // const expiresIn = this.configService.get<string>('JWT_EXPIRES_IN') || '24h';
    return jwt.sign({ ...user }, this.secretKey, {
      expiresIn: this.expiresIn,
    });
  }

  /**
   * 生成hash密码
   * @param password 明文密码
   * @returns hash后的密码
   */
  async hashPassword(password: string): Promise<string> {
    const salt = await bcrypt.genSalt(10);
    return bcrypt.hash(password, salt);
  }

  /**
   * 验证密码
   * @param password 明文密码
   * @param hashedPassword 加密密码
   * @returns 是否匹配
   */
  async validatePassword(
    password: string,
    hashedPassword: string,
  ): Promise<boolean> {
    return bcrypt.compare(password, hashedPassword);
  }

  /**
   * 校验token
   */
  verifyToken(token: string): any {
    return jwt.verify(token, this.secretKey);
  }

  /**
   * 获取token中的数据
   */
  decodeToken(token: string): any {
    return jwt.decode(token);
  }
}
